package com.rui.study.commons.study.captcha;

import com.rui.study.commons.util.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

/**
 * @program: study_20180903
 * @description: 验证码生成器
 * @author: Yaowr
 * @create: 2018-09-25 10:49
 **/
public class CaptchaGenerator {

    private int width = 95;// 图片宽
    private int height = 25;// 图片高

    private static final Logger LOGGER = LoggerFactory.getLogger(CaptchaGenerator.class);

    public CaptchaGenerator() {
    }

    public CaptchaGenerator(int width, int height) {
        this.width = width;
        this.height = height;
    }

    /**
     * 随机字体
     * @return
     */
    private Font randomFont() {
        Font[] fonts = new Font[]{
                new Font("Times New Roman", Font.ROMAN_BASELINE, 18),
                new Font("Fixedsys", Font.CENTER_BASELINE, 18)
        };
        return fonts[RandomUtil.nextInt(fonts.length)];
    }

    /**
     * 随机颜色颜色
     */
    private Color randomColor(int fc, int bc) {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + RandomUtil.nextInt(bc - fc - 16);
        int g = fc + RandomUtil.nextInt(bc - fc - 14);
        int b = fc + RandomUtil.nextInt(bc - fc - 18);
        return new Color(r, g, b);
    }

    /**
     * 生成随机图片
     */
    public void generate(String randomStr, OutputStream outputStream) {
        /* BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类 */
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);

        /* 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作 */
        Graphics g = image.getGraphics();

        /* /图片大小 */
        g.fillRect(0, 0, width, height);

        /* 设置字体以及大小 */
        g.setFont(randomFont());

        /* 字体颜色 */
        g.setColor(randomColor(110, 133));

        /* 绘制干扰线 */
        drawLine(g, 40);  // 干扰线数量

        /* 绘制随机字符 */
        drawString(g, randomStr);

        g.dispose();
        try {
            // 将内存中的图片通过流动形式输出到客户端
            ImageIO.write(image, "JPEG", outputStream);
        } catch (Exception e) {
            LOGGER.error("图片写到输出流 失败>>>>   ", e);
        }
    }

    /**
     * 绘制字符串
     */
    private void drawString(Graphics g, String randomStr) {
        char[] chars = randomStr.toCharArray();
        for (int n = 0; n < randomStr.length(); n++) {
            g.setFont(randomFont());
            g.setColor(new Color(RandomUtil.nextInt(101), RandomUtil.nextInt(111), RandomUtil
                    .nextInt(121)));
            g.translate(RandomUtil.nextInt(3), RandomUtil.nextInt(3));
            g.drawString(String.valueOf(chars[n]), 13 * (n + 1), 16);
        }
    }

    /**
     * 绘制干扰线
     */
    private void drawLine(Graphics g, int total) {
        for (int i = 0; i <= total; i++) {
            int x = RandomUtil.nextInt(width);
            int y = RandomUtil.nextInt(height);
            int xl = RandomUtil.nextInt(13);
            int yl = RandomUtil.nextInt(15);
            g.drawLine(x, y, x + xl, y + yl);
        }
    }


    public static void main(String[] args) throws FileNotFoundException {
        CaptchaGenerator generator = new CaptchaGenerator();
        File dir = new File("d:\\temp\\captcha");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        /* 随机字符串 */
        String randomStr = RandomUtil.nextDigital(4);

        OutputStream outputStream = new FileOutputStream(new File(dir, "hehe.jpg"));
        generator.generate(randomStr, outputStream);

        LOGGER.info("随机字符串：{}", randomStr);
    }
}
